package moves;

import jade.core.AID;
import jade.core.Agent;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import jade.proto.AchieveREInitiator;
import moves.Movement.Action;
import moves.Movement.Direction;
import agents.UtilsAgents;

public class MovementSender {

	AID my;
	AID destination;
	Agent myAgent;

	/**
	 * Implements sending turn decisions to a higher Agent
	 * 
	 * @param agent
	 *            - the agent that sends the message
	 * @param aid
	 *            - the AID of the Agent that wants to move
	 * @param destination
	 *            - the type of agent to send it to. Example:
	 *            UtilsAgents.COORDINATOR_AGENT
	 */

	public MovementSender(Agent agent, AID aid, String destination) {
		this.my = aid;
		myAgent = agent;

		// Search for destination Agent
		ServiceDescription searchCriterion = new ServiceDescription();
		searchCriterion.setType(destination);
		this.destination = UtilsAgents.searchAgentS(agent, searchCriterion)
				.get(0);

		// searchAgent is a blocking method, so we will obtain always a correct
		// AID
	}

	/**
	 * Sends a movement order
	 * 
	 * @param d
	 *            - direction to move, example: Direction.UP
	 */
	public void go(Movement.Direction d) {
		Movement m = new Movement(this.my, Action.GO, d);
		send(m);
	}

	/****************************************/

	public void go_floor(Movement.Direction d) {
		Movement m = new Movement(this.my, Action.GO, d);
		send(m);
	}

	public void out(Movement.Direction d) {
		try {
			System.out.println("going out");
			Movement m = new Movement(my, Action.OUT, d);
			send(m);
		} catch (Exception e) {
			e.toString();
		}
	}

	public void put(Movement.Direction step) {
		Movement m = new Movement(this.my, Action.PUT, step);
		send(m);

	}

	public void cure(Direction step) {
		Movement m = new Movement(this.my, Action.CURE, step);
		send(m);
	}

	public void setDest(AID sender) {
		// TODO Auto-generated method stub
		this.destination = sender;
	}

	/**************************************/
	private void send(Movement m) {
		// Send the message
		System.out.println(this.myAgent.getLocalName() + "send movement"
				+ m.getDirection() + "to" + destination);
		ACLMessage requestInicial = new ACLMessage(ACLMessage.REQUEST);
		requestInicial.clearAllReceiver();
		requestInicial.addReceiver(destination);
		requestInicial.setProtocol(agents.UtilsAgents.PROTOCOL_MOVEMENT);

		try {
			requestInicial.setContentObject(m);
		} catch (Exception e) {
			System.out.println("Exception in send" + e.toString());
			e.printStackTrace();
		}
		// we add a behavior that sends the message and waits for an answer
		myAgent.addBehaviour(new MessageSender(myAgent, requestInicial));
	}

	class MessageSender extends AchieveREInitiator {
		private static final long serialVersionUID = 7709846829251324278L;

		public MessageSender(Agent arg0, ACLMessage arg1) {
			super(arg0, arg1);
		}
	}

}
